package com.justspeak;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.justspeak.database.SqlHelper;
import com.justspeak.module.CourseDownloadInfo;
import com.justspeak.module.CourseInfo;
import com.justspeak.util.io.FileUtils;

/**
 * copyright justspeak 2010
 * 
 * @date 2011-9-13 V1.0初始作成
 * @author chenlong
 * @version V1.0
 * @brief BaseAdapter的定义
 * @since 1.0
 * @descript 此类用来显示和管理下载界面的。
 * @todo 未完成的事项
 */
public class FileDownManageActivity extends ListActivity {
    /*
     * private ImageView showDownImage; private TextView showName; private
     * TextView showSize; private ProgressBar progressbar; private Button
     * btn_stop; private Button btn_back;
     */

    private List<CourseDownloadInfo> list = new ArrayList<CourseDownloadInfo>();// 显示需要下载的文件信息
    private SqlHelper sqlhelper; // 数据库帮助类
    private FileUtils fileutils;; // 文件工具累
    CourseDownloadInfo info; // 下载信息

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.downmanage);
	sqlhelper = SqlHelper.getInstance(FileDownManageActivity.this,
		"DowFileDataBase");
	fileutils = new FileUtils();
    }

    @Override
    protected void onResume() {
	super.onResume();
	Intent tent = getIntent(); // 得到传过来需要下载的参数
	List ci =(List)tent.getSerializableExtra("lessons");
	for(int i=0;i<ci.size();i++){
           CourseInfo info=(CourseInfo)ci.get(i);
           CourseDownloadInfo downloadInfo=new CourseDownloadInfo();
           downloadInfo.setFilename(info.getMp3Name());
           downloadInfo.setFilesize(Integer.valueOf(info.getMp3Size()));
           downloadInfo.setStartPosition(0);
           downloadInfo.setState(0);
           downloadInfo.setBookName(info.getBook());
           downloadInfo.setUnitName(info.getUnitname());
           sqlhelper.saveNeedDownFileInfo(downloadInfo);
	}
	
	// List<CourseDownloadInfo> cour = sqlhelper.QueryFileInfoFromDataBase(
	// "state=?", new String[] { "0" });
	List<CourseDownloadInfo> cour = sqlhelper.QueryFileInfoFromDataBase(
		null, null);
	if (cour != null && cour.size() != 0)
	    for (CourseDownloadInfo in : cour) {
		if (!list.contains(in))
		    list.add(in);
	    }

	setListAdapter(new MyBaseAdapter(getListView()));
    }

    static class ViewHolder {
	TextView fileNameView;
	TextView txtvSizeView;
	TextView updatePercentView;
	ProgressBar progressbar;
	ImageButton btn_start;
	ImageView image_view;
    }

    /*
     * 基本数据适配器
     */
    class MyBaseAdapter extends BaseAdapter {
	LayoutInflater inflater;
	DownFileCallBack callback;

	public MyBaseAdapter(ListView listview) {
	    super();
	    listview.setDivider(new ColorDrawable(Color.GRAY));
	    listview.setDividerHeight(2);
	}

	public View getView(int position, View vie, ViewGroup parent) {
	    info = list.get(position);
	    ViewHolder viewHolder;
	    if (inflater == null)
		inflater = LayoutInflater.from(FileDownManageActivity.this);
	    vie = inflater.inflate(R.layout.downmanage_item, null);
	    viewHolder = new ViewHolder();

	    viewHolder.image_view = (ImageView) vie
		    .findViewById(R.id.show_DownImage);
	    viewHolder.fileNameView = (TextView) vie
		    .findViewById(R.id.show_DownFileName);
	    viewHolder.txtvSizeView = (TextView) vie
		    .findViewById(R.id.show_DownFileSize);
	    viewHolder.updatePercentView = (TextView) vie
		    .findViewById(R.id.show_updatePrecent);
	    viewHolder.progressbar = (ProgressBar) vie
		    .findViewById(R.id.show_downProgressBar);
	    viewHolder.btn_start = (ImageButton) vie
		    .findViewById(R.id.btn_stopdown);
	    // viewHolder.txtvSizeView.setText(info.getFilesize() / 1024 + "K");
	    viewHolder.fileNameView.setText(info.getFilename());

	    String downurl = "http://10.0.2.2:8080/test" + File.separator
		    + info.getFilename();
	    String saveurl = fileutils.createSdDir("test").toString();
	    viewHolder.btn_start.setOnClickListener(new MyOnclickListener(
		    downurl, saveurl + File.separator + info.getFilename(),
		    info.getStartPosition(), info.getFilesize(), viewHolder));
	    return vie;
	}

	public long getItemId(int position) {
	    return 0;
	}

	public Object getItem(int position) {
	    return null;
	}

	public int getCount() {
	    return list.size();
	}
    };

    /*
     * 下载监听事件
     */
    private class MyOnclickListener implements OnClickListener {
	private String downUrl;
	private String filename;
	private int start_position;
	private int filesize;
	private ViewHolder viewHolder;
	private boolean flag = false; // 标志是暂停还是在下载
	FileDownloading filedown = null;

	private MyOnclickListener(String downUrl, String filename,
		int start_position, int filesize, ViewHolder viewHolder) {
	    this.downUrl = downUrl;
	    this.filename = filename;
	    this.start_position = start_position;
	    this.filesize = filesize;
	    this.viewHolder = viewHolder;
	}

	public void onClick(View v) {
	    final ImageView image_view = viewHolder.image_view;
	    final TextView size_tv = viewHolder.txtvSizeView;
	    final TextView percent_tv = viewHolder.updatePercentView;
	    final ProgressBar pbar = viewHolder.progressbar;

	    if (!flag) {
		// 每次点击下载或暂停是，都从数据库读取已经下载的初始值
		start_position = sqlhelper
			.queryHadDownloadedByFileName(filename
				.substring(filename.lastIndexOf("/") + 1));
		// 显示界面的下载图标
		image_view.setImageResource(R.drawable.show_downloading);
		// 更改数据库中下载文件的状态
		sqlhelper.updateDownFilePropertyByFileFlag(
			new String[] { "state" }, new String[] { "1" },
			filename);

		int filePercent = Double.valueOf(
			start_position * 1.0 / filesize * 100).intValue();
		if (size_tv != null) {
		    size_tv.setText("共" + filesize / 1024 + "KB/已下载"
			    + (start_position / 1024) + "KB");
		}
		if (pbar != null) {
		    pbar.setProgress(filePercent);
		}
		if (percent_tv != null) {
		    percent_tv.setText(filePercent + "%");
		}

		filedown = new FileDownloading(downUrl, filename,
			start_position, filesize);
		filedown.downFile(filename, new DownFileCallBack() {
		    public void updateProgressBar(int curPosition,// 用于更新精度条、百分比等界面的方法
			    String downUrl) {

			// System.out.println("--------updateingProgressBar--------");
			// 当收到更新视图消息时，计算已完成下载百分比，同时更新进度条信息
			int curProgress = (Double.valueOf((curPosition * 1.0
				/ filesize * 100))).intValue();
			if (size_tv != null) {
			    size_tv.setText("共" + filesize / 1024 + "KB/已下载"
				    + curPosition / 1024 + "KB");
			}

			if (pbar != null) {
			    pbar.setProgress(curProgress);
			}

			if (percent_tv != null) {
			    percent_tv.setText(curProgress + "%");
			}

			if (curProgress == 100) {
			    // 更新已经下载完成的文件的已下载和状态属性
			    sqlhelper.updateDownFilePropertyByFileFlag(
				    new String[] { "state", "startPosition" },
				    new String[] { "2", filesize + "" },
				    filename.substring(filename
					    .lastIndexOf("/") + 1));
			    // 更新完成后从ListView中删除次下载完成的列表
			    // getListView().removeView((LinearLayout)
			    // (pbar.getParent().getParent().getParent()));
			    System.out
				    .println("------Download_success----------");
			    Toast.makeText(
				    FileDownManageActivity.this,
				    filename.substring(filename
					    .lastIndexOf("/") + 1)
					    + "下载完成！", Toast.LENGTH_SHORT)
				    .show();
			}
		    }
		});
		flag = true; // 标记正在下载
	    } else {
		flag = false; // 标记暂停
		// 显示界面的暂停的图标
		image_view.setImageResource(R.drawable.show_stop1);
		filedown.discureptDownloadThread();// 保存暂停时已经下载的文件字节数
		int hadDownloaded = filedown.getHadDownload();
		System.out.println("--------stopping---------" + hadDownloaded);
		sqlhelper.updateDownFilePropertyByFileFlag(new String[] {
			"startPosition", "state" }, new String[] {
			hadDownloaded + "", "0" }, filename.substring(filename
			.lastIndexOf("/") + 1));
	    }
	}
    }

    // 内部线程类
    class FileDownloading {
	private String urlStr;
	private String fileName;
	// private File file;
	private int startPosition;
	// private int curPosition;
	private int filesize;
	// 用于标识当前线程是否下载完成
	private boolean finished = false;
	private int downloadSize = 0;
	FileDownloadThread fdt = null;

	public FileDownloading(String urlStr, String fileName,
		int startPosition, int filesize) {
	    this.urlStr = urlStr;
	    this.fileName = fileName;
	    this.startPosition = startPosition;
	    // this.curPosition = startPosition;
	    this.filesize = filesize;
	}

	public void downFile(final String fileURL,
		final DownFileCallBack callback) {

	    final Handler handler = new Handler() {
		public void handleMessage(Message msg) {
		    int arg1 = msg.arg1;
		    String fileurl = (String) msg.obj;
		    callback.updateProgressBar(arg1, fileurl);
		}
	    };
	    fdt = new FileDownloadThread(handler, urlStr, fileName,
		    startPosition, filesize);
	    fdt.start();
	}

	public boolean isFinished() {
	    return finished;
	}

	public int getDownloadSize() {
	    return downloadSize;
	}

	// 点击暂停 打断下载线程
	public void discureptDownloadThread() {
	    if (fdt != null)
		fdt.sotpDownloadThread();
	}

	public int getHadDownload() { // 返回已经下载的字节数
	    return fdt.getHadDownloadSize();
	}

    }

    class FileDownloadThread extends Thread {
	private Handler hand;
	private static final int BUFFER_SIZE = 1024;
	private String urlStr;
	private String fileName;
	private int startPosition;
	private int curPosition;
	private int filesize;
	File file;
	// boolean finished = false;
	boolean download_flag = false;

	private FileDownloadThread(Handler hand, String urlStr,
		String fileName, int startPosition, int fileSize) {
	    this.hand = hand;
	    this.urlStr = urlStr;
	    this.urlStr = urlStr;
	    this.fileName = fileName;
	    this.startPosition = startPosition;
	    this.curPosition = startPosition;
	    this.filesize = fileSize;
	}

	public void run() {
	    BufferedInputStream bis = null;
	    RandomAccessFile fos = null;
	    byte[] buf = new byte[BUFFER_SIZE];
	    URLConnection con = null;
	    try {
		URL url = new URL(urlStr);
		con = url.openConnection();
		file = new File(fileName);
		if (!file.exists())
		    // file.delete();
		    file.createNewFile();
		setHeader(con, urlStr);
		con.setAllowUserInteraction(true);
		// int total = con.getContentLength();
		// 设置当前线程下载的起点，终点
		con.setRequestProperty("Range", "bytes=" + startPosition + "-"
			+ filesize);
		// 使用java中的RandomAccessFile 对文件进行随机读写操作
		fos = new RandomAccessFile(this.file, "rwd");
		// 设置开始写文件的位置
		fos.seek(startPosition);
		bis = new BufferedInputStream(con.getInputStream());
		// 开始循环以流的形式读写文件
		while (!download_flag) {
		    int len = bis.read(buf, 0, BUFFER_SIZE);
		    if (len == -1) {
			break;
		    }
		    fos.write(buf, 0, len);
		    curPosition = curPosition + len;
		    Message message = Message.obtain();
		    message.arg1 = curPosition;
		    message.obj = urlStr;
		    hand.sendMessage(message);
		    /*
		     * if (curPosition > total) { downloadSize += len -
		     * (curPosition - total) + 1; } else { downloadSize += len;
		     * }
		     */
		    try {
			Thread.sleep(20);
		    } catch (InterruptedException e) {
			// TODO Auto-generated catch block
		    }
		}
		bis.close();
		fos.close();
	    } catch (IOException e) {
		// 网络异常或断掉则保持当前已下载的字节数据及更新状态为未下载
		sqlhelper.updateDownFilePropertyByFileFlag(new String[] {
			"startPosition", "state" }, new String[] {
			curPosition + "", "0" }, fileName.substring(fileName
			.lastIndexOf("/") + 1));
	    }
	}

	public int getHadDownloadSize() {// 得到当前已下载的字节数
	    return curPosition;
	}

	public void sotpDownloadThread() {// 暂停下载
	    download_flag = true;
	}
    }

    // 设置Connection下载的属性
    private void setHeader(URLConnection http, String url) {
	http.setConnectTimeout(5 * 1000);
	// http.setRequestProperty("method", "GET");
	http
		.setRequestProperty(
			"Accept",
			"image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
	http.setRequestProperty("Accept-Language", "zh-CN");
	http.setRequestProperty("Referer", url);
	http.setRequestProperty("Charset", "UTF-8");
	http
		.setRequestProperty(
			"User-Agent",
			"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
	http.setRequestProperty("Connection", "Keep-Alive");
    }
}
